package com.bingquan.company.method;

@FunctionalInterface
interface Operation {
    int operation(int a, int b);
}

interface Creater<T> {
    T get();
}

interface TestInt {
    int cp(Test222 test1, Test222 test2);
}


class Test222 {
    public static Test222 create(Creater<Test222> creater) {
        return creater.get();
    }

    private int operate(int a, int b, Operation operation) {
        System.out.println("call Test22 operate method");
        return operation.operation(a, b);
    }

    private static int add(int a, int b ) {
        System.out.println("calls Test22 add method");
        return a + b;
    }

    private int sub(int a, int b) {
        return a - b;
    }

    public int testM(Test222 test) {
        System.out.println("call Test22 testM method");
        return 0;
    }

    public void test(TestInt testInt) {
        System.out.println("call Test222 test method");
        Test222 t1 = Test222.create(Test222::new);
        Test222 t2 = Test222.create(Test222::new);
        testInt.cp(t1, t2);
    }

    /**
     * java8 方法调用
     * @param args
     */
    public static void main(String[] args) {
        /**
         * 构造方法引用
         * 使用方式：Class::new
         */
        Test222 test = Test222.create(Test222::new);
        System.out.println("======create");

        /**
         * 静态方法引用
         * 使用方式：Class::staticMethod
         * 经过测试该语法使用规范：
         * 1、 operate(int a, int b, Operation operation) 第三个参数必须是函数式接口，接口不能有其他抽象方法；
         * 2、Test222::add 返回值与“Operation的唯一接口”返回值相同；
         * 3、Test222::add 入参与“Operation的唯一接口” 入参一致
         * 4、add方法名与“Operation的唯一接口”方法名可以不同
         * 5、 test.operate(1, 2, Test222::add)执行顺序：①先执行test。operate方法 ②再执行实现Operation函数接口的add方法
         */
        test.operate(1, 2, Test222::add);
        System.out.println("======operate");

        /**
         * 对象的实例方法引用
         * 使用方式：instance::method
         */
        test.operate(1, 2, test::sub);
        System.out.println("======operate===the second");

        /**
         * 类的实例方法引用
         * 使用方式：Class::method
         */
        test.test(Test222::testM);
        System.out.println("======");
    }
}
